<?php

namespace App\WeChat\Message;

use App\Model\MpInviteCodeModel;
use App\Model\MpQrDefModel;
use App\Model\UserModel;
use App\WeChat\Message\Activity\Activity;
use App\WeChat\Message\Activity\InviteMessage;
use App\WeChat\WeChatUtil;
use CURLFile;
use EasySwoole\Component\Csp;
use EasySwoole\HttpClient\Exception\InvalidUrl;
use EasySwoole\HttpClient\HttpClient;
use EasySwoole\WeChat\Bean\OfficialAccount\Message\Image;
use EasySwoole\WeChat\Bean\OfficialAccount\Message\Text;
use EasySwoole\WeChat\Bean\OfficialAccount\RequestMsg;


class OnMessageScan
{
    public static function handle(RequestMsg $msg)
    {
        if (Activity::isActivity()) {
            return self::parseQr($msg);
        } else {
            return self::activityEnd($msg);
        }
    }

    /**
     * 活动结束的响应
     * @param RequestMsg $msg
     * @return Text
     */
    private static function activityEnd(RequestMsg $msg): Text
    {
        $util = new WeChatUtil();
        $accessToken = $util->getAccessToken();
        $nickname = $util->brzComGetUnionIdByOpenid($accessToken, $msg->getFromUserName(), 'nickname');//根据openid获取用户昵称
        $text = new Text();
        $text->setContent(InviteMessage::activityEndMessage($nickname));
        return $text;
    }

    /**
     * 解析领书二维码
     * @param RequestMsg $msg
     * @return Image|Text|null
     */
    private static function parseQr(RequestMsg $msg)
    {
        $sceneId = (int)$msg->getEventKey();
        $uid = (new UserModel())->getUidByOpenId($msg->getFromUserName());
        if (!$uid) {
            echo "用户不存在\n";
            return null;
        }
        $start = microtime(true);
        $def = (new MpQrDefModel())->findById($sceneId);
        if (!$def) {
            echo "资源不存在\n";
            $text = new Text();
            $text->setToUserName($msg->getFromUserName());
            $text->setContent("资源不存在");
            return $text;
        }
        $img = $def ['img'];
        //文字消息
        self::sendTextMsg($msg->getFromUserName(), $def['name'], $def['need']);
        $rand = uniqid();
        $bgPath = EASYSWOOLE_ROOT . "/Temp/mp_poster_bg_{$rand}.jpg";//背景图
        $iconPath = EASYSWOOLE_ROOT . "/Temp/mp_poster_icon_{$rand}.jpg";//头像
        $csp = new Csp();
        //并发1：下载背景图片
        $csp->add('t1', function () use ($img, $bgPath) {
            $cli = new HttpClient($img);
            file_put_contents($bgPath, $cli->get()->getBody());
            return 't1 done';
        });
        //并发2：获取用户信息并下载头像
        $csp->add('t2', function () use ($uid, $iconPath) {
            $user = (new UserModel())->getColumnByUid($uid, ['icon']);
            $icon = $user['icon'];
            $cli = new HttpClient($icon);
            file_put_contents($iconPath, $cli->get()->getBody());
            return 't2 done';
        });
        //并发3：获取邀请码
        $csp->add('t3', function () use ($uid, $sceneId, $msg) {
            return (new MpInviteCodeModel())->getCode($uid, $sceneId, $msg->getFromUserName());
        });
        $cspRet1 = $csp->exec();
        $img1 = imagecreatefromjpeg($bgPath);
        $img2 = imagecreatefromjpeg($iconPath);
        //写入邀请码
        $code = (string)$cspRet1['t3'];
        $font = EASYSWOOLE_ROOT . '/yahei.ttf';
        $color = imagecolorallocate($img1, 50, 50, 50);
        for ($i = 0; $i < strlen($code); $i++) {
            $char = $code[$i];
            imagettftext($img1, 43, 0, 175 + 92 * $i, imagesy($img1) - 482, $color, $font, $char);
        }
        //合并图片
        self::imagePress($iconPath);
        $iconSize = imagesx($img2) - 30;
        imagecopymerge($img1, $img2, 65, 200, 10, 0, $iconSize, $iconSize, 100);
        imagepng($img1, $bgPath);
        //上传图片到微信服务器
        $accessToken = (new WeChatUtil())->getAccessToken();
        try {
            $wxRes = (new HttpClient("https://api.weixin.qq.com/cgi-bin/media/upload?access_token={$accessToken}&type=image"))
                ->post([
                    'media' => new CURLFile($bgPath)
                ])
                ->getBody();
            $mediaId = json_decode($wxRes, true)['media_id'];
            //销毁资源
            imagedestroy($img1);
            imagedestroy($img2);
            sgo(function () use ($bgPath, $iconPath) {
                unlink($bgPath);
                unlink($iconPath);
            });
            $img = new Image();
            $img->setMediaId($mediaId);
            echo '耗时：' . (microtime(true) - $start), PHP_EOL;
            return $img;
        } catch (InvalidUrl $e) {
            echo $e->getMessage(), PHP_EOL;
            return null;
        }
    }

    /**
     * 发送文字消息
     * @param string $openid
     * @param string $giftName
     * @param int $need
     */
    private static function sendTextMsg(string $openid, string $giftName, int $need): void
    {
        sgo(function () use ($openid, $giftName, $need) {
            $util = new WeChatUtil();
            $accessToken = $util->getAccessToken();
            $text = InviteMessage::onAScanTextMessage($giftName, $need);
            $util->sendTextMsg($openid, $text, $accessToken);
        });
    }

    /**
     * 图片缩放
     * @param string $filepath
     * @param float $percent
     * @return bool
     */
    private static function imagePress(string $filepath, float $percent = 0.5)
    {
        // 获得新的图片大小
        list($width, $height) = getimagesize($filepath);
        $new_width = $width * $percent;
        $new_height = $height * $percent;
        // 重新取样
        $image_p = imagecreatetruecolor($new_width, $new_height);
        $image = imagecreatefromjpeg($filepath);
        imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
        // 输出
        return imagejpeg($image_p, $filepath, 100);
    }

}